//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//

/* Copyright ?1999,2000,2001 Intel Corp.  */
/*++

Module Name:

  pwrbutton.c

Abstract:

  This module is intended as a home for threads that monitor and manage suspend/resume
  on the platform. Current implementation monitors SW6, EXT_WAKE<0> on the Littleton
  main board.

Notes:


--*/

#include <windows.h>
#include <windev.h>
#include <bsp.h>
#include <xllp_intc.h>
#include <pmpolicy.h>
#include "xllp_i2c.h"
#include "xllp_gpio_plat.h"
#include "GPX_XLLP.h"
#include "monahans.h"
#include "MMC2120.h"
#define I2C_MUTEX_NAME		TEXT("I2C_CONTROL") 
#ifdef DEBUGMSG
#undef DEBUGMSG
#define DEBUGMSG RETAILMSG 
#endif
 volatile int *g_pI2CRegs;
 volatile int *g_pOSTRegs;
 volatile int *g_pMFPRegs;
 volatile int *g_pGPIORegs;
static HANDLE        g_I2CMutex = NULL;
BOOL WINAPI DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
            DEBUGMSG(1, (TEXT("[MAG]DllEntry: DLL_PROCESS_ATTACH (PID=x%08x)\r\n"), GetCurrentProcessId()));
            break;
    
        case DLL_PROCESS_DETACH:
            DEBUGMSG(1, (TEXT("[MAG]DllEntry: DLL_PROCESS_DETACH (PID=x%08x)\r\n"), GetCurrentProcessId()));
            break;
    }
    return (TRUE);
}



void MAG_UnMapAddresses(void)
{

	if(g_pMFPRegs!=NULL)
   		VirtualFree((PVOID)g_pMFPRegs,0,MEM_RELEASE);
	
    if(g_pI2CRegs!=NULL)
   		VirtualFree((PVOID)g_pI2CRegs,0,MEM_RELEASE);
	
	if(g_pOSTRegs!=NULL)
   		VirtualFree((PVOID)g_pOSTRegs,0,MEM_RELEASE);
	
	if(g_pGPIORegs!=NULL)
   		VirtualFree((PVOID)g_pGPIORegs,0,MEM_RELEASE);
	
    return;
}

BOOL MAG_MapAddresses(void)
{

    if ( g_pMFPRegs==NULL ) 
    {
        PHYSICAL_ADDRESS ioPhysicalBase = {MONAHANS_BASE_REG_PA_MFP, 0 };
        g_pMFPRegs = (volatile int *)MmMapIoSpace(ioPhysicalBase, 0x800,FALSE); 

        if ( g_pMFPRegs==NULL )
        {
            RETAILMSG(1, (_T("[MAG]MAP MFP Register error ")));
            return FALSE;            
        }
    }

    DEBUGMSG(ZONE_INIT, (_T("[MAG]Map Read MFP Register 0x%x\r\n"),g_pMFPRegs));

    if (g_pI2CRegs==NULL ) 
    {
        PHYSICAL_ADDRESS ioPhysicalBase = {MONAHANS_BASE_REG_PA_I2C, 0 };
        g_pI2CRegs = (volatile int *)MmMapIoSpace(ioPhysicalBase, 0x100,FALSE); 

        if ( g_pI2CRegs==NULL )
        {
            RETAILMSG(1, (_T("[[MAG]]MAP I2CBase Register error \r\n")));
            return FALSE;            
        }
    }
        
    DEBUGMSG(ZONE_INIT, (_T("[MAG]Map Read I2C Register0x%x\r\n"),g_pI2CRegs ));
        
    if ( g_pOSTRegs == NULL ) 
    {
        PHYSICAL_ADDRESS ioPhysicalBase = {MONAHANS_BASE_REG_PA_OST, 0 };
        g_pOSTRegs = (volatile int *)MmMapIoSpace(ioPhysicalBase, 0xF0,FALSE); 

        if ( g_pOSTRegs==NULL )
        {
            RETAILMSG(1, (_T("[MAG]MAP m_OSTBase Register error \r\n")));
            return FALSE;            
        }
    }

    DEBUGMSG(ZONE_INIT, (_T("[MAG]Map Read OST Register0x%x\r\n"),g_pOSTRegs ));
    
    if (g_pGPIORegs == NULL) {

        PHYSICAL_ADDRESS ioPhysicalBase = {MONAHANS_BASE_REG_PA_GPIO, 0 };
        g_pGPIORegs = (volatile int *)MmMapIoSpace(ioPhysicalBase, 0xF0,FALSE); 

        if ( g_pGPIORegs==NULL )
        {
            RETAILMSG(1, (_T("[MAG]MAP m_GPIOBase Register error \r\n")));
            return FALSE;            
        }
    }
    return TRUE;

}

VOID MAG_PowerUp(VOID) 
{

	return;
} // PWB_PowerUp

BOOL MAG_PowerDown(VOID) 
{

	return(TRUE);
} // PWB_PowerDown

BOOL MAG_Deinit(DWORD p1) 
{
 
    MAG_UnMapAddresses();

    return (TRUE);
}

DWORD MAG_Init(LPCTSTR pContext,
  LPCVOID lpvBusContext
)
{

	//BOOL result;
    if (g_I2CMutex == NULL)
        g_I2CMutex=CreateMutex(NULL, FALSE, I2C_MUTEX_NAME);
	
	if (!MAG_MapAddresses())
	{
	    DEBUGMSG(1, (TEXT("[MAG]MAG_Init: PWB_InitializeAddresses Failed\r\n")));
	    goto CleanUp;
	}

	//XllpMfpSetAfDs((P_XLLP_VUINT32_T)g_pMFPRegs, XLLP_MFP_PIN_GPIO102_OFFSET, XLLP_MFP_ALT_FN_0,XLLP_MFP_DS_04X);
	//XllpMfpSetAfDs((P_XLLP_VUINT32_T)g_pMFPRegs, XLLP_MFP_PIN_GPIO103_OFFSET, XLLP_MFP_ALT_FN_0,XLLP_MFP_DS_04X);
	
	//XllpGpioSetDirection((P_XLLP_GPIO_T)g_pGPIORegs, XLLP_GPIO_FM_RST, XLLP_GPIO_DIRECTION_OUT);
	//XllpGpioSetDirection((P_XLLP_GPIO_T)g_pGPIORegs, XLLP_GPIO_FM_BUSSEL2,XLLP_GPIO_DIRECTION_OUT);
	

    DEBUGMSG(1, (TEXT("[MAG]MAG_Init: Success\r\n")));
    return(TRUE);

 CleanUp:

    MAG_Deinit(0);
    return (FALSE);
}

DWORD MAG_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode) 
{
    DEBUGMSG(1, (TEXT("[MAG]MAG_Open:\r\n")));
	//XllpGpioSetOutputLevel((P_XLLP_GPIO_T)g_pGPIORegs, XLLP_GPIO_FM_RST, XLLP_LO);
	//XllpGpioSetOutputLevel((P_XLLP_GPIO_T)g_pGPIORegs, XLLP_GPIO_FM_RST, XLLP_HI);
    return(0x11345678);
}

BOOL MAG_Close(DWORD dwData) 
{
    DEBUGMSG(1, (TEXT("[MAG]MAG_Close:\r\n")));
	MAG_PowerDown();
    return (TRUE);
}

DWORD MAG_Read (DWORD dwData,  LPVOID pBuf, DWORD Len) 
{
	XLLP_UINT8_T pBuffer[2];
	if (WaitForSingleObject(g_I2CMutex, 3000) != WAIT_OBJECT_0)
		DEBUGMSG(1, (TEXT("[MAG] Waiting for Single Object failed %d \r\n"),GetLastError()));
	pBuffer[0] = 0x00;
	pBuffer[1] = 0x01;
	XllpI2CWrite((P_XLLP_I2C_T)g_pI2CRegs,
		(P_XLLP_OST_T)g_pOSTRegs,
		MMC2120_I2C_ADDRESS,
		pBuffer,
		sizeof(pBuffer), 
		TRUE);
	XllpOstDelayMicroSeconds((P_XLLP_OST_T)g_pOSTRegs, 5);
	pBuffer[0] = 0x01;
	XllpI2CWrite((P_XLLP_I2C_T)g_pI2CRegs,
		(P_XLLP_OST_T)g_pOSTRegs,
		MMC2120_I2C_ADDRESS,
		pBuffer,
		1, 
		TRUE);
	XllpI2CRead((P_XLLP_I2C_T)g_pI2CRegs,
	 			(P_XLLP_OST_T)g_pOSTRegs,
	 			MMC2120_I2C_ADDRESS,
	 			pBuf,
	 			4,
	 			TRUE);
	ReleaseMutex(g_I2CMutex);
    return (0);
}

DWORD MAG_Write(DWORD dwData, LPCVOID pBuf, DWORD Len) 
{
    return (0);
}

DWORD MAG_Seek (DWORD dwData, long pos, DWORD type) 
{
    return (DWORD)-1;
}

BOOL MAG_IOControl(DWORD hOpenContext,DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{

	switch(dwCode)
	{
		default:
			break;
	}
    return(TRUE);
}
